#ifndef _DANIEL_KERR_GLTURN_H
#define _DANIEL_KERR_GLTURN_H

#include "driver.h"
#include "glmove.h"
#include "gltkg.h"
#include "glwait.h"
#include "logicPlanet.h"
#include "transitMgr.h"

struct myTurns
{
	move_C myShip;
	vector <move_C> pturns;
};

class turn_C
{
	public:
		void initialize(universe_C &god,int fps)
		{
			turn.clear();

			atShip=true;
			wasShip=false;
			pInd=0;

			move_C tempMove;
			for(int i=0;i<god.NOPLAY();++i)
			{
				turn.push_back(myTurns());

				turn[i].myShip.init(god,god.slocs()[i],fps,false);

				for(int j=0;j<god.NOP();++j)
				{
					tempMove.init(god,j,fps,true);
					turn[i].pturns.push_back(tempMove);
				}
			}
		}

		void switchPlayer(universe_C &god,transitMgr &boss,int fps)
		{
			displayWait();

			if(++pInd>=god.NOPLAY())
			{
				pInd-=god.NOPLAY();
				god.myUniverse()->turn();
			}

			boss.turn(pInd);

			list<transitInfo> all = boss.getList();
			std::list<transitInfo>::iterator i = all.begin();
			while(i != all.end())
			{
				// Check to make sure either my sure planet is enemy
				if((god.myUniverse()->getOwner(i->getDest()) != i->getForce().getOwner())&&(god.myUniverse()->getOwner(i->getDest()) != NEUTRAL))
				{
					if((i->getForce().getOwner() == pInd)&&(i->getTurns() == 1))
					{			
						vector<string> attackdata = god.ppinfo(i->getDest());
						attackdata.push_back("Home:  " + god.pname(i->getSrc()));				//attacker source planet
						attackdata.push_back("Force: " + gitoa(i->getForce().getSize(),5));		//attacker size
						attackdata.push_back("Force Readiness: " + i->getForce().getRdyStr());		//attacker readiness

						switch(displayTurnKillGo(attackdata))
						{
							case 0:
								{
									myMSG.add("Turn around!");
									if(wasShip)
									{
										turn[pInd].myShip.movetoPlanet(god,i->getSrc(),fps,true);
									}
									
									transitInfo t(i->getDest(),i->getSrc(),god.weight(i->getSrc(),i->getDest())-1,i->getForce());
									std::list<transitInfo>::iterator k = i;
									all.erase(k);
									i = all.begin();
									all.push_front(t);
								}
								break;
							default: break;
						}
					}
				}
				if(i != all.end())
				{++i;}
			}

			boss.setList(all);

			while(boss.nextDone())
			{
				if(!attack(boss.getForce(),god.myUniverse()->getPlanet(boss.getDest()),0,0))
				{
					if(wasShip)
					{
						turn[pInd].myShip.gotoPlanet(god,boss.getSrc());
						turn[pInd].myShip.turntoPlanet(god,boss.getDest(),fps);
					}
				}
			}

			atShip=true;
			wasShip=false;
		}

		void switchTurn(universe_C &god,transitMgr &boss,int fps,bool tookit=true)
		{
			if(atShip&&tookit)
			{
				tq = god.myUniverse()->turnQueue(pInd);

				atShip=false;
				wasShip=true;
			
				for(unsigned int i=0;i<tq.size();++i)
				{
					if(tq.front()==turn[pInd].myShip.At())
					{
						tq.pop();
						if(tq.empty())
						{switchPlayer(god,boss,fps);}
						wasShip=false;
						break;
					}
					else
					{
						cycleQueue(tq);
						wasShip=false;
					}
				}
			}
			else if(!tq.empty()&&tookit)
			{
				tq.pop();
				if(tq.empty())
				{switchPlayer(god,boss,fps);}
				wasShip=false;
			}
			else if(!tq.empty())
			{
				cycleQueue(tq);
				wasShip=false;
			}

			updateTR_Text(god);
		}

		// Accesors
		int getInd()	{ return pInd; }
		bool ship()		{ return atShip; }

		// Move Class Reference Functions
			bool update(universe_C &god,transitMgr &boss,int fps)
			{
				if(atShip)
				{
					if(turn[pInd].myShip.update(god,fps))
					{switchTurn(god,boss,fps); return true;}
				}
				else
				{
					if(turn[pInd].pturns[tq.front()].update(god,fps))
					{switchTurn(god,boss,fps); return true;}
				}
				return false;
			}

			// Game Motion
			void gotoPlanet(universe_C &god,int index)
			{
				if(atShip)	{turn[pInd].myShip.gotoPlanet(god,index);}
				else		{turn[pInd].pturns[tq.front()].gotoPlanet(god,index);}
			}
			void movetoPlanet(universe_C &god,int index,int fps,bool back=false)
			{
				if(atShip)	{turn[pInd].myShip.movetoPlanet(god,index,fps,back);}
				else
				{
					if(god.myUniverse()->getOwner(index) != NEUTRAL)
					{turn[pInd].pturns[tq.front()].movetoPlanet(god,index,fps,back);}
				}
			}

			void lookLeft(universe_C &god,int fps)
			{
				if(atShip)	{turn[pInd].myShip.lookLeft(god,fps);}
				else		{turn[pInd].pturns[tq.front()].lookLeft(god,fps);}
			}
			void lookRight(universe_C &god,int fps)
			{
				if(atShip)	{turn[pInd].myShip.lookRight(god,fps);}
				else		{turn[pInd].pturns[tq.front()].lookRight(god,fps);}
			}

			// Accesors and Checkers
			int At()
			{
				if(atShip)	{return turn[pInd].myShip.At();}
				else		{return turn[pInd].pturns[tq.front()].At();}
			}
			int LookAt()
			{
				if(atShip)	{return turn[pInd].myShip.LookAt();}
				else		{return turn[pInd].pturns[tq.front()].LookAt();}
			}
			bool moving()
			{
				if(atShip)	{return turn[pInd].myShip.moving();}
				else		{return turn[pInd].pturns[tq.front()].moving();}
			}

			vector <string> TR_Text()
			{
				if(atShip)	{return turn[pInd].myShip.TR_Text();}
				else		{return turn[pInd].pturns[tq.front()].TR_Text();}
			}
			vector <string> OPT_Text()
			{
				if(atShip)	{return turn[pInd].myShip.OPT_Text();}
				else		{return turn[pInd].pturns[tq.front()].OPT_Text();}
			}
			
			void updateTR_Text(universe_C &god)
			{
				if(atShip)	{turn[pInd].myShip.updateTR_Text(god);}
				else		{turn[pInd].pturns[tq.front()].updateTR_Text(god);}
			}
			void updateOPT_Text(universe_C &god)
			{
				if(atShip)	{turn[pInd].myShip.updateOPT_Text(god);}
				else		{turn[pInd].pturns[tq.front()].updateOPT_Text(god);}
			}

	private:
		bool atShip,wasShip;
		int pInd;
		queue <int> tq;
		vector <myTurns> turn;
};

#endif